package net.pinnoocle.playservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import net.pinnoocle.playcommon.exception.ShopException;
import net.pinnoocle.playcommon.response.BaseResult;
import net.pinnoocle.playcommon.response.ErrorCode;
import net.pinnoocle.playcommon.utils.ConvertUtils;
import net.pinnoocle.playcommon.utils.DownloadImageLocal;
import net.pinnoocle.playcommon.utils.HelpUtils;
import net.pinnoocle.playcommon.utils.JwtUtil;
import net.pinnoocle.playdao.dao.*;
import net.pinnoocle.playdao.entity.*;
import net.pinnoocle.playdao.entity.page.PageModel;
import net.pinnoocle.playdao.entity.page.PageQuery;
import net.pinnoocle.playdao.entity.shopPc.*;
import net.pinnoocle.playdao.entity.web.QrCodeVo;
import net.pinnoocle.playdao.entity.web.user.UserScriptListPageVo;
import net.pinnoocle.playservice.service.CommonService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.bind.SchemaOutputResolver;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 剧本基本信息(Script)表服务实现类
 *
 * @author ye
 * @since 2021-10-20 20:24:00
 */
@Service("scriptService")
@Slf4j
public class ScriptServiceImpl extends ServiceImpl<ScriptDao, Script>{


    @Value("${upload.folder}")
    private String uploadFolder;

    @Value("${upload.mapUrl}")
    private String uploadMapUrl;

    @Autowired
    ScriptRoleDao scriptRoleDao;
    @Autowired
    ScriptIntroDao scriptIntroDao;
    @Autowired
    ScriptLabelDao scriptLabelDao;
    @Autowired
    ScriptCateDao scriptCateDao;
    @Autowired
    ScriptLevelDao scriptLevelDao;
    @Autowired
    ScriptEvaluateDao scriptEvaluateDao;
    @Autowired
    ShopServiceImpl shopService;
    @Autowired
    UserServiceImpl userService;
    @Autowired
    ScriptLibraryServiceImpl scriptLibraryService;
    @Autowired
    CommonService commonService;
    @Autowired
    GroupServiceImpl groupService;
    @Autowired
    ShopStatisticsServiceImpl shopStatisticsService;
    @Autowired
    ScriptLibraryRoleServiceImpl scriptLibraryRoleService;

    /**
     * 剧本列表---分页
     * @param params
     * @return
     */
    public PageModel<ScriptListVo> scriptList(ScriptListSearchParams params){
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(params.getPage()));
        pageMap.put("pageSize",String.valueOf(params.getPageSize()));

        String shopId = userService.getGlobalShopId();
        params.setShopId(shopId);
        Page<ScriptListVo> list = this.baseMapper.scriptList(
                new PageQuery<ScriptLabel>(pageMap).getPage(),params);
        List<ScriptListVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        //ids换取names
        for (ScriptListVo script : records){
            String cateNames = getNamesByIds(script.getScriptCateId(), 0);
            script.setScriptCateName(cateNames);
            String labelNames = getNamesByIds(script.getScriptLabelId(), 1);
            script.setScriptLabelName(labelNames);
            String levelNames = getNamesByIds(script.getScriptLevelId(), 2);
            script.setScriptLevelName(levelNames);
        }
        return new PageModel<>(list, records);
    }

    /**
     * 添加剧本
     * @param params
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean saveScript(SaveScriptParams params){
        String shopId = userService.getGlobalShopId();
        if(StringUtils.isBlank(shopId)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"登录信息获取失败，请重新登录");
        }
        try {
            Script script = ConvertUtils.sourceToTarget(params, Script.class);
            script.setShopId(shopId);
            script.setCreatedTime(new Date());
            boolean save = this.save(script);
            if(save && StringUtils.isNotBlank(script.getScriptId())){
                List<SaveScriptRoleParams> roleParams = params.getRoleParams();
                for (SaveScriptRoleParams role : roleParams){
                    ScriptRole scriptRole = ConvertUtils.sourceToTarget(role, ScriptRole.class);
                    scriptRole.setScriptId(script.getScriptId());
                    scriptRoleDao.insert(scriptRole);
                }
                //同步到剧本库
                syncScriptLibrary(script);
                //添加内容
                ScriptIntro scriptIntro = new ScriptIntro();
                scriptIntro.setScriptId(script.getScriptId());
                scriptIntro.setContent(params.getContent());
                return scriptIntroDao.insert(scriptIntro) > 0;
            }
        } catch (Exception e) {
            log.info("添加剧本失败："+e.getMessage());
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 剧本编辑
     * @param params
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateScript(SaveScriptParams params){
        try {
            String scriptId = params.getScriptId();
            Script script = ConvertUtils.sourceToTarget(params, Script.class);
            boolean updateResult = this.updateById(script);
            if(updateResult){
                //兼容旧数据
                ScriptIntro scriptIntro = scriptIntroDao.selectOne(new QueryWrapper<ScriptIntro>()
                        .lambda()
                        .eq(ScriptIntro::getScriptId, scriptId)
                        .last("LIMIT 1"));
                if(Objects.isNull(scriptIntro)){
                    ScriptIntro scriptIntroData = new ScriptIntro();
                    scriptIntroData.setScriptId(scriptId);
                    scriptIntroData.setContent(params.getContent());
                    scriptIntroDao.insert(scriptIntroData);
                }else{
                    scriptIntro.setContent(params.getContent());
                    scriptIntroDao.updateById(scriptIntro);
                }
                //先批量下架该剧本角色
                this.baseMapper.batchDisableScriptRole(scriptId,1);
                List<SaveScriptRoleParams> roleParams = params.getRoleParams();
                if(CollectionUtils.isNotEmpty(roleParams)){
                    for (SaveScriptRoleParams role : roleParams){
                        String roleId = role.getRoleId();
                        ScriptRole scriptRole = ConvertUtils.sourceToTarget(role, ScriptRole.class);
                        if(StringUtils.isNotBlank(roleId)){
                            scriptRole.setIsDisable(0);
                            scriptRoleDao.updateById(scriptRole);
                        }else {
                            scriptRole.setScriptId(scriptId);
                            scriptRoleDao.insert(scriptRole);
                        }
                    }
                }
            }
            return updateResult;
        } catch (Exception e) {
            log.info("修改剧本失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 删除剧本
     * @param scriptId
     */
    public boolean deleteScript(String scriptId){
        int count = groupService.count(new QueryWrapper<Group>()
                .lambda()
                .eq(Group::getScriptId, scriptId)
                .le(Group::getGroupType, 2));
        if(count > 0){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"该剧本正在开局或等待开局，暂时不能删除");
        }
        try {
            this.removeById(scriptId);
            scriptIntroDao.delete(new QueryWrapper<ScriptIntro>()
                    .lambda()
                    .eq(ScriptIntro::getScriptId,scriptId));
            scriptRoleDao.delete(new QueryWrapper<ScriptRole>()
                    .lambda()
                    .eq(ScriptRole::getScriptId,scriptId));
            return true;
        } catch (Exception e) {
            log.info("删除剧本失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 剧本上下架
     * @param scriptId
     * @param isDisable
     * @return
     */
    public boolean scriptUpAndDown(String scriptId, Integer isDisable){
        try {
            Script script = new Script();
            script.setScriptId(scriptId);
            script.setIsDisable(isDisable);
            return this.updateById(script);
        } catch (Exception e) {
            log.info("剧本上下架失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 剧本详情
     * @param scriptId
     * @return
     */
    public ScriptDetailVo scriptDetail(String scriptId){
        Script script = this.getById(scriptId);
        ScriptIntro scriptIntro = scriptIntroDao.selectOne(new QueryWrapper<ScriptIntro>()
                .lambda()
                .eq(ScriptIntro::getScriptId, scriptId)
                .last("LIMIT 1"));
        //ids换取names
        String cateNames = getNamesByIds(script.getScriptCateId(), 0);
        script.setScriptCateName(cateNames);
        String labelNames = getNamesByIds(script.getScriptLabelId(), 1);
        script.setScriptLabelName(labelNames);
        String levelNames = getNamesByIds(script.getScriptLevelId(), 2);
        script.setScriptLevelName(levelNames);
        ScriptDetailVo scriptDetailVo = ConvertUtils.sourceToTarget(script,ScriptDetailVo.class);
        //剧本角色
        List<ScriptRoleDetailVo> scriptRoleDetailVos = roleDetail(scriptId);
        scriptDetailVo.setRoleDetailVos(scriptRoleDetailVos);
        //剧本口碑
        ScriptDetailEvaluateVo evaluateVo = evaluateDetail(scriptId);
        evaluateVo.setPlayNum(script.getPlayNum());
        evaluateVo.setWantPlayNum(script.getWantNum());
        scriptDetailVo.setEvaluateVo(evaluateVo);
        //店铺名称
        Shop shop = shopService.getById(script.getShopId());
        scriptDetailVo.setShopName(shop.getShopName());
        if(Objects.nonNull(scriptIntro)){
            scriptDetailVo.setContent(scriptIntro.getContent());
        }
        //增加剧本访问量
        shopStatisticsService.grandShopStatisticsScript(script.getShopId());
        return scriptDetailVo;
    }

    /**
     * 获取剧本内容
     * @param scriptId
     * @return
     */
    public String getScriptContent(String scriptId){
        ScriptIntro scriptIntro = scriptIntroDao.selectOne(new QueryWrapper<ScriptIntro>()
                .lambda()
                .eq(ScriptIntro::getScriptId, scriptId)
                .last("LIMIT 1"));
        if(Objects.nonNull(scriptIntro)){
            return scriptIntro.getContent();
        }
        return "";
    }

    /**
     * 剧本分类列表---分页
     * @param param
     * @return
     */
    public PageModel<ScriptCateListPageVo> cateListWithPage(BaseShopSearch param){
        String shopId = param.getShopId();

        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(param.getPage()));
        pageMap.put("pageSize",String.valueOf(param.getPageSize()));

        if(Objects.isNull(shopId)){
            shopId = userService.getGlobalShopId();
            param.setShopId(shopId);
        }
        Page<ScriptCateListPageVo> list = this.baseMapper.cateListWithPage(
                new PageQuery<ScriptCate>(pageMap).getPage(),param);
        List<ScriptCateListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        return new PageModel<>(list, records);
    }

    /**
     * 剧本标签列表---分页
     * @param param
     * @return
     */
    public PageModel<ScriptLabelListPageVo> labelListWithPage(BaseShopSearch param){
        String shopId = param.getShopId();

        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(param.getPage()));
        pageMap.put("pageSize",String.valueOf(param.getPageSize()));

        if(Objects.isNull(shopId)){
            shopId = userService.getGlobalShopId();
            param.setShopId(shopId);
        }
        Page<ScriptLabelListPageVo> list = this.baseMapper.labelListWithPage(
                new PageQuery<ScriptLabel>(pageMap).getPage(),param);
        List<ScriptLabelListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        return new PageModel<>(list, records);
    }

    /**
     * 剧本级别列表---分页
     * @param param
     * @return
     */
    public PageModel<ScriptLevelListPageVo> levelListWithPage(BaseShopSearch param){
        String shopId = param.getShopId();
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(param.getPage()));
        pageMap.put("pageSize",String.valueOf(param.getPageSize()));

        if(Objects.isNull(shopId)){
            shopId = userService.getGlobalShopId();
        }
        param.setShopId(shopId);
        Page<ScriptLevelListPageVo> list = this.baseMapper.levelListWithPage(
                new PageQuery<ScriptLevel>(pageMap).getPage(),param);
        List<ScriptLevelListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        return new PageModel<>(list, records);
    }

    /**
     * 剧本分类列表---无分页
     * @return
     */
    public List<ScriptCateListVo> cateList(){
        String shopId = userService.getGlobalShopId();
        List<ScriptCate> cateList = scriptCateDao.selectList(new QueryWrapper<ScriptCate>()
                .lambda()
                .eq(ScriptCate::getShopId, shopId)
                .orderByAsc(ScriptCate::getSort));
        if(CollectionUtils.isEmpty(cateList)){
            return new ArrayList<>();
        }
        return ConvertUtils.sourceToTarget(cateList,ScriptCateListVo.class);
    }

    /**
     * 剧本标签列表---无分页
     * @return
     */
    public List<ScriptLabelListVo> labelList(){
        String shopId = userService.getGlobalShopId();
        List<ScriptLabel> labelList = scriptLabelDao.selectList(new QueryWrapper<ScriptLabel>()
                .lambda()
                .eq(ScriptLabel::getShopId, shopId)
                .orderByAsc(ScriptLabel::getSort));
        if(CollectionUtils.isEmpty(labelList)){
            return new ArrayList<>();
        }
        return ConvertUtils.sourceToTarget(labelList,ScriptLabelListVo.class);
    }

    /**
     * 剧本级别列表---无分页
     * @return
     */
    public List<ScriptLevelListVo> levelList(){
        String shopId = userService.getGlobalShopId();
        List<ScriptLevel> levelList = scriptLevelDao.selectList(new QueryWrapper<ScriptLevel>()
                .lambda()
                .eq(ScriptLevel::getShopId, shopId)
                .orderByAsc(ScriptLevel::getSort));
        if(CollectionUtils.isEmpty(levelList)){
            return new ArrayList<>();
        }
        return ConvertUtils.sourceToTarget(levelList,ScriptLevelListVo.class);
    }

    /**
     * 添加剧本分类
     * @param params
     * @return
     */
    public boolean saveCate(SaveScriptCateParams params){
        String shopId = JwtUtil.getUserId();
        if(StringUtils.isBlank(shopId)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"登录信息获取失败，请重新登录");
        }
        try {
            ScriptCate scriptCate = ConvertUtils.sourceToTarget(params, ScriptCate.class);
            scriptCate.setShopId(shopId);
            scriptCate.setCreatedTime(new Date());
            return scriptCateDao.insert(scriptCate) > 0;
        } catch (Exception e) {
            log.info("剧本分类添加失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 添加剧本标签
     * @param params
     * @return
     */
    public boolean saveLabel(SaveScriptLabelParams params){
        String shopId = JwtUtil.getUserId();
        if(StringUtils.isBlank(shopId)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"登录信息获取失败，请重新登录");
        }
        try {
            ScriptLabel scriptLabel = ConvertUtils.sourceToTarget(params, ScriptLabel.class);
            scriptLabel.setShopId(shopId);
            scriptLabel.setCreatedTime(new Date());
            return scriptLabelDao.insert(scriptLabel) > 0;
        } catch (Exception e) {
            log.info("剧本标签添加失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 添加剧本级别
     * @param params
     * @return
     */
    public boolean saveLevel(SaveScriptLevelParams params){
        String shopId = JwtUtil.getUserId();
        if(StringUtils.isBlank(shopId)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"登录信息获取失败，请重新登录");
        }
        try {
            ScriptLevel scriptLevel = ConvertUtils.sourceToTarget(params, ScriptLevel.class);
            scriptLevel.setShopId(shopId);
            scriptLevel.setCreatedTime(new Date());
            return scriptLevelDao.insert(scriptLevel) > 0;
        } catch (Exception e) {
            log.info("剧本级别添加失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 剧本分类编辑
     * @param params
     * @return
     */
    public boolean updateCate(SaveScriptCateParams params){
        try {
            ScriptCate scriptCate = ConvertUtils.sourceToTarget(params, ScriptCate.class);
            return scriptCateDao.updateById(scriptCate) > 0;
        } catch (Exception e) {
            log.info("剧本分类编辑失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 剧本标签编辑
     * @param params
     * @return
     */
    public boolean updateLabel(SaveScriptLabelParams params){
        try {
            ScriptLabel scriptLabel = ConvertUtils.sourceToTarget(params, ScriptLabel.class);
            return scriptLabelDao.updateById(scriptLabel) > 0;
        } catch (Exception e) {
            log.info("剧本标签编辑失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 剧本级别编辑
     * @param params
     * @return
     */
    public boolean updateLevel(SaveScriptLevelParams params){
        try {
            ScriptLevel scriptLevel = ConvertUtils.sourceToTarget(params, ScriptLevel.class);
            return scriptLevelDao.updateById(scriptLevel) > 0;
        } catch (Exception e) {
            log.info("剧本级别编辑失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 剧本份分类删除
     * @param cateId
     * @return
     */
    public boolean deleteCate(Integer cateId){
        try {
            int num = scriptCateDao.deleteById(cateId);
            return num > 0;
        } catch (Exception e) {
            log.info("剧本分类删除失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 剧本标签删除
     * @param labelId
     * @return
     */
    public boolean deleteLabel(Integer labelId){
        try {
            int num = scriptLabelDao.deleteById(labelId);
            return num > 0;
        } catch (Exception e) {
            log.info("剧本标签删除失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 剧本级别删除
     * @param levelId
     * @return
     */
    public boolean deleteLevel(Integer levelId){
        try {
            int num = scriptLevelDao.deleteById(levelId);
            return num > 0;
        } catch (Exception e) {
            log.info("剧本级别删除失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 剧本角色列表
     * @param scriptId
     * @return
     */
    public List<ScriptRoleDetailVo> roleDetail(String scriptId){
        List<ScriptRole> scriptRoles = scriptRoleDao.selectList(new QueryWrapper<ScriptRole>()
                .lambda()
                .eq(ScriptRole::getScriptId, scriptId)
                .eq(ScriptRole::getIsDisable, 0));
        if(CollectionUtils.isEmpty(scriptRoles)){
            return new ArrayList<>();
        }
        return ConvertUtils.sourceToTarget(scriptRoles,ScriptRoleDetailVo.class);
    }

    /**
     * 剧本口碑详情
     * @param scriptId
     * @return
     */
    public ScriptDetailEvaluateVo evaluateDetail(String scriptId){
        ScriptDetailEvaluateVo evaluateVo = new ScriptDetailEvaluateVo();
        int totalNum = 0;
        int[] starNumArr = new int[5];
        for (int i = 0; i <= 4; i++) {
            starNumArr[i] = scriptEvaluateDao.selectCount(new QueryWrapper<ScriptEvaluate>()
                    .lambda()
                    .eq(ScriptEvaluate::getScriptId, scriptId)
                    .eq(ScriptEvaluate::getStarNum, (i+1)));
            totalNum = totalNum+starNumArr[i];
        }
        evaluateVo.setStarOne(HelpUtils.getPercent(starNumArr[0],totalNum));
        evaluateVo.setStarSecond(HelpUtils.getPercent(starNumArr[1],totalNum));
        evaluateVo.setStarThree(HelpUtils.getPercent(starNumArr[2],totalNum));
        evaluateVo.setStarFour(HelpUtils.getPercent(starNumArr[3],totalNum));
        evaluateVo.setStarFive(HelpUtils.getPercent(starNumArr[4],totalNum));
        evaluateVo.setScriptId(scriptId);
        evaluateVo.setEvaluateNumber(totalNum);
        //计算口碑平均分
        Double totalScore = getTotalScore(starNumArr, totalNum);
        evaluateVo.setScore(totalScore);
        return evaluateVo;
    }

    /**
     * 计算剧本平均分
     * @param scriptId
     * @return
     */
    public double calculateScriptScore(String scriptId){
        int totalNum = 0;
        int[] starNumArr = new int[5];
        for (int i = 0; i <= 4; i++) {
            starNumArr[i] = scriptEvaluateDao.selectCount(new QueryWrapper<ScriptEvaluate>()
                    .lambda()
                    .eq(ScriptEvaluate::getScriptId, scriptId)
                    .eq(ScriptEvaluate::getStarNum, (i+1)));
            totalNum = totalNum+starNumArr[i];
        }
        return getTotalScore(starNumArr, totalNum);
    }

    /**
     * 通过id组合换取name组合
     * @param ids
     * @param type 0 剧本分类 1 剧本标签 2 剧本级别
     * @return
     */
    public String getNamesByIds(String ids,Integer type){
        if(ids == null || StringUtils.isBlank(ids)){
            return "";
        }
        //id=>name映射
        Map<Integer, String> idName = new HashMap<>();
        if(type == 0){
            List<ScriptCate> list = scriptCateDao.selectList(null);
            idName = list.stream().collect(Collectors.toMap(ScriptCate::getCateId, ScriptCate::getCateName));
        }else if(type == 1){
            List<ScriptLabel> list = scriptLabelDao.selectList(null);
            idName = list.stream().collect(Collectors.toMap(ScriptLabel::getLabelId, ScriptLabel::getLabelName));
        }else if(type == 2){
            List<ScriptLevel> list = scriptLevelDao.selectList(null);
            idName = list.stream().collect(Collectors.toMap(ScriptLevel::getLevelId, ScriptLevel::getLevelName));
        }
        if(CollectionUtils.isNotEmpty(idName)){
            if(ids.indexOf(",") > 0){
                StringBuilder names = new StringBuilder();
                String[] idList = ids.split(",");
                for (String id : idList){
                    String name = Objects.nonNull(idName.get(Integer.valueOf(id))) ? idName.get(Integer.valueOf(id)) : "";
                    names.append(name);
                    if (names.length() > 0) {
                        names.append(",");
                    }
                }
                return names.substring(0,names.length()-1);
            }else{
                return Objects.nonNull(idName.get(Integer.valueOf(ids))) ? idName.get(Integer.valueOf(ids)) : "";
            }
        }
        return "";
    }

    /**
     * name换取id
     * @param name
     * @param type
     * @param shopId
     * @return
     */
    public Integer getIdByName(String name,String shopId,Integer type){
        if(name == null || StringUtils.isBlank(name)){
            return 0;
        }
        //name=>id
        Map<String, Integer> idName = new HashMap<>();
        if(type == 0){
            List<ScriptCate> list = scriptCateDao.selectList(new QueryWrapper<ScriptCate>()
                    .lambda()
                    .eq(ScriptCate::getShopId,shopId));
            idName = list.stream().collect(Collectors.toMap(ScriptCate::getCateName, ScriptCate::getCateId,(v1, v2 )->{
                return v2;
            }));
        }else if(type == 1){
            List<ScriptLabel> list = scriptLabelDao.selectList(new QueryWrapper<ScriptLabel>()
                    .lambda()
                    .eq(ScriptLabel::getShopId,shopId));
            idName = list.stream().collect(Collectors.toMap(ScriptLabel::getLabelName, ScriptLabel::getLabelId,(v1, v2 )->{
                return v2;
            }));
        }else if(type == 2){
            List<ScriptLevel> list = scriptLevelDao.selectList(new QueryWrapper<ScriptLevel>()
                    .lambda()
                    .eq(ScriptLevel::getShopId,shopId));
            idName = list.stream().collect(Collectors.toMap(ScriptLevel::getLevelName, ScriptLevel::getLevelId,(v1, v2 )->{
                return v2;
            }));
        }
        if(CollectionUtils.isNotEmpty(idName)){
            return Objects.nonNull(idName.get(name)) ? idName.get(name) : 0;
        }
        return 0;
    }

    /**
     * 计算口碑平均分
     * @param starNumArr
     * @param totalNum
     * @return
     */
    private Double getTotalScore(int[] starNumArr,int totalNum){
        if(totalNum == 0){
            return 0.00;
        }
        //人数*分值
        int starNum = starNumArr[4]*10+starNumArr[3]*8+starNumArr[2]*6+starNumArr[1]*4+starNumArr[0]*2;
        return HelpUtils.setScaleNumber((double) starNum / totalNum);
    }

    /**
     * 剧本库初始化
     * @return
     */
    public boolean scriptLibraryInit(){
        List<ScriptLibrary> scriptLibraries = this.baseMapper.scriptLibraryInit();
        String[] cateList = new String[]{"还原","开放","封闭","半封闭","本格","变格","城限","独家","实景","演绎","换装","盒装"};
        List<String> resultList = new ArrayList<>(cateList.length);
        Collections.addAll(resultList,cateList);
        for (ScriptLibrary item : scriptLibraries){
            String labelNames = item.getScriptLabelName();
            List<String> labelName = Arrays.asList(labelNames.split(","));
            StringBuilder cateStr = new StringBuilder();
            StringBuilder labelStr = new StringBuilder();
            for (String label : labelName){
                if(!label.contains("人") && label.length() > 0){
                    if(resultList.contains(label)){
                        cateStr.append(label);
                        cateStr.append(",");
                    }else{
                        labelStr.append(label);
                        labelStr.append(",");
                    }
                }
            }
            String cate = cateStr.toString();
            String label = labelStr.toString();
            cate = cate.length() > 1 ? cate.substring(0,cate.length()-1) : cate;
            label = label.length() > 1 ? label.substring(0,label.length()-1) : label;
            item.setScriptCateName(cate);
            item.setScriptLabelName(label);
            boolean save = scriptLibraryService.save(item);
            if(save){
                //添加剧本库角色
                String libraryId = item.getLibraryId();
                List<ScriptLibraryRole> scriptLibraryRoles = this.baseMapper.scriptLibraryRole(item.getDramaId());
                for (ScriptLibraryRole role : scriptLibraryRoles){
                    role.setLibraryId(libraryId);
                    String image = role.getHeadPortrait();
                    String imageName = image .substring(image .lastIndexOf("/")+1);
                    String imageUrl = DownloadImageLocal.downloadPicture(image, imageName,uploadFolder+"script/",uploadMapUrl);
                    role.setHeadPortrait(imageUrl);
                    scriptLibraryRoleService.save(role);
                }
            }
        }
        return true;
    }

    /**
     * 剧本库
     * @param params
     * @return
     */
    public PageModel<ScriptLibraryListPageVo> scriptLibrary(ScriptLibraryListSearchParams params){
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(params.getPage()));
        pageMap.put("pageSize",String.valueOf(params.getPageSize()));

        String shopId = userService.getGlobalShopId();
        Page<ScriptLibraryListPageVo> list = this.baseMapper.scriptLibrary(
                new PageQuery<ScriptLevel>(pageMap).getPage(),params);
        List<ScriptLibraryListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        for (ScriptLibraryListPageVo item : records){
            item.setCoverImage(uploadMapUrl+item.getCoverImage());
            //是否已选择
            int count = this.count(new QueryWrapper<Script>().lambda()
                    .eq(Script::getShopId, shopId)
                    .eq(Script::getLibraryId, item.getLibraryId()));
            item.setIsSelected(count > 0 ? 1 : 0);
        }
        return new PageModel<>(list, records);
    }

    /**
     * 总后台的剧本库(忽略是否选择判断)
     * @param params
     * @return
     */
    public PageModel<ScriptLibraryListPageVo> scriptLibraryForAdmin(ScriptLibraryListSearchParams params){
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(params.getPage()));
        pageMap.put("pageSize",String.valueOf(params.getPageSize()));

        String shopId = userService.getGlobalShopId();
        Page<ScriptLibraryListPageVo> list = this.baseMapper.scriptLibrary(
                new PageQuery<ScriptLevel>(pageMap).getPage(),params);
        List<ScriptLibraryListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        for (ScriptLibraryListPageVo item : records){
            item.setCoverImage(uploadMapUrl+item.getCoverImage());
        }
        return new PageModel<>(list, records);
    }

    /**
     * 剧本库剧本详情
     * @param libraryId
     * @return
     */
    public ScriptLibraryListPageVo scriptLibraryDetail(String libraryId){
        ScriptLibrary scriptLibrary = scriptLibraryService.getById(libraryId);
        ScriptLibraryListPageVo scriptLibraryDetail = ConvertUtils.sourceToTarget(scriptLibrary, ScriptLibraryListPageVo.class);
        scriptLibraryDetail.setCoverImage(uploadMapUrl+scriptLibraryDetail.getCoverImage());
        return scriptLibraryDetail;
    }

    /**
     * 拉取剧本库
     * @param libraryId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean selectScriptFromLibrary(String libraryId){
        String shopId = userService.getGlobalShopId();
        ScriptLibrary scriptLibrary = scriptLibraryService.getById(libraryId);
        if(Objects.isNull(scriptLibrary)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"剧本库不存在该剧本");
        }
        int count = this.count(new QueryWrapper<Script>().lambda()
                .eq(Script::getShopId, shopId)
                .eq(Script::getLibraryId, libraryId));
        if(count > 0){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"你的店铺已存在该剧本，请勿重复拉取");
        }
        //剧本库角色
        List<ScriptLibraryRole> scriptRoles = scriptLibraryRoleService.list(new QueryWrapper<ScriptLibraryRole>()
                .lambda()
                .eq(ScriptLibraryRole::getLibraryId, libraryId));
        try {
            String scriptCateName = scriptLibrary.getScriptCateName();
            String scriptLabelName = scriptLibrary.getScriptLabelName();
            String scriptLevelName = scriptLibrary.getScriptLevelName();
            String newCateIds;
            String newLabelIds;
            if(scriptCateName.contains(",")) {
                List<String> cateNameList = Arrays.asList(scriptCateName.split(","));
                StringBuilder cateIds = new StringBuilder();
                for (String item : cateNameList) {
                    Integer cateId = getIdByName(item, shopId, 0);
                    //店铺没这个类型
                    if (cateId == 0 && StringUtils.isNotBlank(item)) {
                        ScriptCate scriptCate = new ScriptCate();
                        scriptCate.setShopId(shopId);
                        scriptCate.setCateName(item);
                        scriptCate.setCreatedTime(new Date());
                        scriptCateDao.insert(scriptCate);
                        cateId = scriptCate.getCateId();
                    }
                    cateIds.append(cateId);
                    cateIds.append(",");
                }
                newCateIds = cateIds.substring(0,cateIds.length()-1);
            }else{
                Integer cateId = getIdByName(scriptCateName,shopId,0);
                if(cateId == 0 && StringUtils.isNotBlank(scriptCateName)){
                    ScriptCate scriptCate = new ScriptCate();
                    scriptCate.setShopId(shopId);
                    scriptCate.setCateName(scriptCateName);
                    scriptCate.setCreatedTime(new Date());
                    scriptCateDao.insert(scriptCate);
                    cateId = scriptCate.getCateId();
                }
                newCateIds = cateId+"";
            }
            if(scriptLabelName.contains(",")) {
                List<String> labelNameList = Arrays.asList(scriptLabelName.split(","));
                StringBuilder labelIds = new StringBuilder();
                for (String item : labelNameList) {
                    Integer labelId = getIdByName(item, shopId, 1);
                    //店铺没这个标签
                    if (labelId == 0 && StringUtils.isNotBlank(item)) {
                        ScriptLabel scriptLabel = new ScriptLabel();
                        scriptLabel.setShopId(shopId);
                        scriptLabel.setLabelName(item);
                        scriptLabel.setCreatedTime(new Date());
                        scriptLabelDao.insert(scriptLabel);
                        labelId = scriptLabel.getLabelId();
                    }
                    labelIds.append(labelId);
                    labelIds.append(",");
                }
                newLabelIds = labelIds.substring(0,labelIds.length()-1);
            }else{
                Integer labelId = getIdByName(scriptLabelName,shopId,1);
                if(labelId == 0 && StringUtils.isNotBlank(scriptLabelName)){
                    ScriptLabel scriptLabel = new ScriptLabel();
                    scriptLabel.setShopId(shopId);
                    scriptLabel.setLabelName(scriptLabelName);
                    scriptLabel.setCreatedTime(new Date());
                    scriptLabelDao.insert(scriptLabel);
                    labelId = scriptLabel.getLabelId();
                }
                newLabelIds = labelId+"";
            }
            Integer levelId = getIdByName(scriptLevelName,shopId,2);
            if(levelId == 0 && StringUtils.isNotBlank(scriptLevelName)){
                ScriptLevel scriptLevel = new ScriptLevel();
                scriptLevel.setShopId(shopId);
                scriptLevel.setLevelName(scriptLevelName);
                scriptLevel.setCreatedTime(new Date());
                scriptLevelDao.insert(scriptLevel);
                levelId = scriptLevel.getLevelId();
            }
            Script script = ConvertUtils.sourceToTarget(scriptLibrary, Script.class);
            script.setShopId(shopId);
            script.setScriptCateId(newCateIds);
            script.setScriptLabelId(newLabelIds);
            script.setScriptLevelId(levelId+"");
            script.setCreatedTime(new Date());
            script.setSourceType(1);
            script.setCoverImage(uploadMapUrl+scriptLibrary.getCoverImage());
            script.setLibraryId(scriptLibrary.getLibraryId());
            boolean saveResult = this.save(script);
            if(saveResult){
                //添加角色
                for (ScriptLibraryRole role : scriptRoles){
                    ScriptRole scriptRole = new ScriptRole();
                    scriptRole.setScriptId(script.getScriptId());
                    scriptRole.setRoleName(role.getRoleName());
                    scriptRole.setRoleIntro(role.getRoleIntro());
                    scriptRole.setHeadPortrait(role.getHeadPortrait());
                    scriptRoleDao.insert(scriptRole);
                }
                //添加内容
                ScriptIntro scriptIntro = new ScriptIntro();
                scriptIntro.setScriptId(script.getScriptId());
                scriptIntro.setContent("");
                return scriptIntroDao.insert(scriptIntro) > 0;

            }
        } catch (Exception e) {
            log.info("选择失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 同步到剧本库
     * @param script
     */
    public void syncScriptLibrary(Script script){
        ScriptLibrary scriptLibrary = ConvertUtils.sourceToTarget(script, ScriptLibrary.class);
        String cateNames = this.getNamesByIds(script.getScriptCateId(), 0);
        String labelNames = this.getNamesByIds(script.getScriptLabelId(), 1);
        String levelName = this.getNamesByIds(script.getScriptLevelId(), 2);
        String coverImage = script.getCoverImage();
        if(coverImage.contains("upload")){
            int pos = coverImage.indexOf("upload");
            String image = coverImage.substring(pos+7);
            scriptLibrary.setCoverImage(image);
        }
        scriptLibrary.setScriptCateName(cateNames);
        scriptLibrary.setScriptLabelName(labelNames);
        scriptLibrary.setScriptLevelName(levelName);
        scriptLibrary.setShopAdd(1);
        scriptLibraryService.save(scriptLibrary);
    }

    /**
     * 剧本海报
     * @param scriptId
     * @return
     */
    public QrCodeVo scriptPoster(String scriptId){
        Script script = this.getById(scriptId);
        if(Objects.isNull(script)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"剧本不存在");
        }
        String shopId = userService.getGlobalShopId();
        Shop shop = shopService.getById(shopId);
        QrCodeVo qrCodeVo = new QrCodeVo();
        String wxUnlimitedCode = commonService.getWxUnlimitedCode(script.getScriptId(), shopId, "pages/drama/drama_detail");
        qrCodeVo.setShopName(shop.getShopName());
        qrCodeVo.setLogo(shop.getLogo());
        qrCodeVo.setImageUrl(script.getCoverImage());
        qrCodeVo.setCodeTitle(script.getScriptName());
        qrCodeVo.setQrCode(wxUnlimitedCode);
        return qrCodeVo;
    }

    /**
     * 门店top5剧本
     * @return
     */
    public List<TopScriptListVo> topScriptFive(){
        String shopId = userService.getGlobalShopId();
        List<Script> list = this.list(new QueryWrapper<Script>()
                .lambda()
                .eq(Script::getShopId, shopId)
                .orderByDesc(Script::getPlayNum)
                .orderByDesc(Script::getCreatedTime)
                .last("LIMIT 5"));
        return ConvertUtils.sourceToTarget(list,TopScriptListVo.class);
    }


    /**
     * 剧本排行（根据组局数）
     * @param type 0 平台剧本 1 店铺剧本
     * @param offset
     * @return
     */
    public List<TopScriptListVo> topScriptByGroup(Integer type,Integer offset){
        if(type == 0){
            List<ScriptLibrary> topLibraryList = scriptLibraryService.list(new QueryWrapper<ScriptLibrary>()
                    .lambda()
                    .eq(ScriptLibrary::getShopAdd, 0)
                    .orderByDesc(ScriptLibrary::getGroupTimes)
                    .orderByDesc(ScriptLibrary::getCreatedTime)
                    .last("LIMIT " + offset));
            return ConvertUtils.sourceToTarget(topLibraryList,TopScriptListVo.class);
        }else if(type == 1){
            List<Script> scriptList = this.list(new QueryWrapper<Script>()
                    .lambda()
                    .orderByDesc(Script::getPlayNum)
                    .orderByDesc(Script::getCreatedTime)
                    .last("LIMIT "+offset));
            return ConvertUtils.sourceToTarget(scriptList,TopScriptListVo.class);
        }
        throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"类型错误");
    }
}